/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package uk.co.dupenois.geometry;

import java.awt.geom.GeneralPath;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;

/**
 *
 * @author mpd209
 */
public class Shape {
    private Vector<Line> lines;
    public Shape(){
        this.lines = new Vector<Line>();
    }

    public void addLine(Coordinate start, Coordinate finish){
        addLine(new Line(start, finish, true));
    }
    public void addLine(Line line){
        this.lines.add(line);
    }
    public Line[] getLines(){
        return lines.toArray(new Line[lines.size()]);
    }
    public Coordinate[] getCoordinates(){
        Vector<Coordinate> coords = new Vector<Coordinate>();
        Line[] lineArr = getLines();
        for(Line line : lineArr){
            if(!coords.contains(line.getStart()))coords.add(line.getStart());
            if(!coords.contains(line.getFinish()))coords.add(line.getFinish());
        }
        return coords.toArray(new Coordinate[coords.size()]);
    }

//    public Triangle[] getTriangleSegments(){
//        Triangle[] triangles = new Triangle[lines.size()-2];
//
//
//
//        return triangles;
//    }

    public double getArea(){
        if(lines.size()<3) return 0;
//        double area = 0;
//        Triangle[] triangles = getTriangleSegments();
//        for(Triangle tri : triangles){
//            area += tri.getArea();
//        }
//        return area;

        //Take area of trapezoid under each line to predetermined lower line,
        //Positive if left to right negative otherwise.

        //Lower line must be less than lowest point
        Coordinate[] coords = getCoordinates();
        List<Coordinate> cList = Arrays.asList(coords);
        //Should put minimum y at top
        Collections.sort(cList, new Comparator<Coordinate>(){
            public int compare(Coordinate arg0, Coordinate arg1) {
                double val = arg0.getY()-arg1.getY();
                if(val<0) return -1;
                if(val>0) return 1;
                return 0;
            }
        });
        //arbitrary reduction
        double bottom_line_y = cList.get(0).getY()-10;
        double area = 0;
        double width;
        double height_to_start;
        double height_to_finish;
        double trapezoid_area;
        for(Line line : lines){
            //If line is right to left this will be negative and give a negative
            //for my area so can just add the areas;
            width = line.getFinish().getX()-line.getStart().getX();
            height_to_start = line.getStart().getY()-bottom_line_y;
            height_to_finish = line.getFinish().getY()-bottom_line_y;
            trapezoid_area = (width/2)*(height_to_start+height_to_finish);
            area += trapezoid_area;
        }
        return area;

    }


    public GeneralPath constructGeneralPath(){
        GeneralPath path = new GeneralPath();
        Line[] myLines = getLines();
        List<Line> lineList = Arrays.asList(myLines);
        Vector<Line> lineVec = new Vector<Line>();
        lineVec.addAll(lineList);
        return constructGeneralPath(lineVec, path, null);

    }
    private GeneralPath constructGeneralPath(Vector<Line> lineVec, GeneralPath path, Coordinate currentLocation){
        if(lineVec.size()< 1) return path;
        Line currentLine = lineVec.remove(0);
        Coordinate start = currentLine.getStart();
        Coordinate finish = currentLine.getFinish();
        if(currentLocation==null || !start.equals(currentLocation)){
            path.moveTo(start.getX(), start.getY());
        }
        path.lineTo(finish.getX(), finish.getY());
        currentLocation = finish;
        return constructGeneralPath(lineVec, path, currentLocation);
    }
}
